﻿using System;
using System.Collections.Generic;
using DataScripter.Database;
using DataScripter.Scripting;
using DataScripter.Scripting.InputSources;
using DataScripter.Scripting.Output;
using DataScripter.Scripting.Output.Sql.SqlServer;
using DataScripter.Scripting.OutputDestinations;
using DataScripter.Scripting.ScriptDefinitions;
using DataScripter.UnitTests.Util;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace DataScripter.UnitTests.EngineTests.ScriptOrder
{
    [TestClass]
    public class TwoRequestsRequestedInOrder
    {
        private readonly IScriptDefinition _scriptDefinition;
        private readonly SqlServerScriptOptions _options;
        private readonly OutputProducerRecorder _producer;

        public TwoRequestsRequestedInOrder()
        {
            Mock<IDatabaseStructure> structureMock = new Mock<IDatabaseStructure>();

            Mock<ITableStructure> abcTableStructureMock = new Mock<ITableStructure>();
            structureMock.Setup(s => s.GetTable("abc")).Returns(abcTableStructureMock.Object);
            abcTableStructureMock.Setup(s => s.ForeignKeys).Returns(new List<IForeignKey>());

            Mock<ITableStructure> defTableStructureMock = new Mock<ITableStructure>();
            structureMock.Setup(s => s.GetTable("def")).Returns(defTableStructureMock.Object);
            IForeignKey keyToAbc = new ForeignKeyInfo("def_abc_FK", "dbo", "def", "d", "dbo", "abc", "a");
            defTableStructureMock.Setup(ts => ts.ForeignKeys).Returns(new List<IForeignKey> {keyToAbc});

            Mock<IDataProducer> dataProducerMock = new Mock<IDataProducer>();
            _producer = new OutputProducerRecorder();

            Engine engine = new Engine();

            IInputSource inputSource = new SqlServerInputSource("", engine);
            engine.RegisterType(inputSource);
            IOutputDestination outputDestination = new FileOutputDestination("", engine);
            engine.RegisterType(outputDestination);

            engine.RegisterType(structureMock.Object);
            inputSource.RegisterType(dataProducerMock.Object);
            outputDestination.RegisterType<IOutputProducer>(_producer);

            _scriptDefinition = new ScriptDefinition("", engine);
            engine.RegisterType(_scriptDefinition);


            _scriptDefinition.RequestScript("abc");
            _scriptDefinition.RequestScript("def");

            _options = new SqlServerScriptOptions(SqlScriptType.Insert)
                           {
                               ScriptOutputType = ScriptOutputType.Memory
                           };

            engine.Script(_options);
        }

        [TestMethod]
        public void ShouldBeInOrderAbcDef()
        {
            _producer.AssertOrder("abc", "def");
        }
    }
}